package com.sky.state;

/**
 * @author : wushikai
 * <p>
 * date : 2020-08-21
 * 状态模式实例
 * 多线程存在 5 种状态，分别为新建状态、就绪状态、运行状态、阻塞状态和死亡状态，各个状态当遇到相关方法调用或事件触发时会转换到其他状态
 */



/**jvm类*/
public class JVM {


    public static void main(String[] args) {
        ThreadContext context=new ThreadContext();
        context.start();
        context.getCPU();
        context.suspend();
        context.resume();
        context.getCPU();
        context.stop();

        // --------------- 不能跨越
       // ThreadContext context1=new ThreadContext();
       // context1.stop();
    }
}

/**环境类*/
class ThreadContext {

    private ThreadState  state;

    public ThreadContext() {
        this.state = new NewState();
    }

    public void setState(ThreadState state) {
        this.state = state;
    }

    public ThreadState getState() {
        return state;
    }

    public void  start(){

        ((NewState)  state).start(this);
    }

    public void getCPU()
    {
        ((Runnable) state).getCpu(this);
    }
    public void suspend()
    {
        ((Running) state).suspend(this);
    }
    public void stop()
    {
        ((Running) state).stop(this);
    }
    public void resume()
    {
        ((Blocked) state).resume(this);
    }


}

//抽象状态类：线程状态
abstract class ThreadState {
    protected String stateName; //状态名


}

class NewState extends ThreadState{

    public NewState() {
        super.stateName = "新建状态";
        System.out.println("当前线程--> 新建状态; ");
    }


    public void start (ThreadContext threadContext){

        System.out.println("调用start() 方法 ->");

        if ("新建状态".equals(stateName)){

            threadContext.setState(new  Runnable()); //父类引用子类对象
        }else{

            System.out.println("当前线程不是新建状态，不能调用start()方法.");
        }
    }

}
/**就绪状态类*/
class Runnable extends ThreadState{

    public Runnable() {
        stateName = "就绪状态";
        System.out.println("当前线程--> 就绪状态; ");
    }

    public void getCpu(ThreadContext threadContext){

        System.out.print("获得CPU时间-->");

        if ("就绪状态".equals(stateName)){

            threadContext.setState(new Running());
        }else{

            System.out.println("当前线程不是就绪状态，不能获得cpu资源.");
        }
    }



}

/*具体状态类:运行状态*/
class Running extends  ThreadState {

    public Running() {
        stateName = "运行状态";
        System.out.println("当前线程处于：运行状态.");


    }

    public void suspend(ThreadContext threadContext){
        System.out.print("调用suspend()方法-->");
        if(stateName.equals("运行状态"))
        {
            threadContext.setState(new Blocked());
        }
        else
        {
            System.out.println("当前线程不是运行状态，不能调用suspend()方法.");
        }


    }

    public void stop(ThreadContext threadContext)
    {
        System.out.print("调用stop()方法-->");
        if(stateName.equals("运行状态"))
        {
            threadContext.setState(new Dead());
        }
        else
        {
            System.out.println("当前线程不是运行状态，不能调用stop()方法.");
        }
    }
}


//具体状态类：阻塞状态
class Blocked extends ThreadState
{
    public Blocked()
    {
        stateName="阻塞状态";
        System.out.println("当前线程处于：阻塞状态.");
    }
    public void resume(ThreadContext threadContext)
    {
        System.out.print("调用resume()方法-->");
        if(stateName.equals("阻塞状态"))
        {
            threadContext.setState(new Runnable());
        }
        else
        {
            System.out.println("当前线程不是阻塞状态，不能调用resume()方法.");
        }
    }
}
//具体状态类：死亡状态
class Dead extends ThreadState
{
    public Dead()
    {
        stateName="死亡状态";
        System.out.println("当前线程处于：死亡状态.");
    }
}
